home *** CD-ROM | disk | FTP | other *** search
- #include "util.h"
- #include "ap.h"
-
- #if DEBUG > 1
- extern int debug;
- extern char *typtab[];
- #endif
-
- /* Standard routines for handling address list element nodes
-
- /* < 1978 B. Borden Wrote initial version of parser code
- * 78-80 D. Crocker Reworked parser into current form
- * Apr 81 K. Harrenstein Hacked for SRI
- * Jun 81 D. Crocker Back in the fold. Finished v7 conversion
- * minor cleanups.
- * repackaging into more complete set of calls
- * Jul 81 D. Crocker ap_free & _alloc check for not 0 or -1
- * malloc() error causes jump to ap_init error
- */
-
- struct ap_prevstruct *ap_fle; /* parse state top of stack */
- /* "fl" => file, but could be other */
-
- int (*ap_gfunc) (); /* Ptr to character get fn */
-
- extern int ap_peek; /* basic parse state info */
- extern int ap_perlev;
- extern int ap_grplev;
-
- extern char *malloc();
-
- /* ******************** LIST NODE PRIMITIVES *********************** */
-
- AP_ptr
- ap_alloc () /* create node, return pointer to it */
- {
- AP_ptr ap;
-
- /* NOSTRICT */
- ap = (AP_ptr) malloc (sizeof (struct ap_node));
- if (ap == (AP_ptr) 0)
- return ((AP_ptr) 0);
-
- ap_ninit (ap);
- return (ap);
- }
-
- ap_ninit (ap)
- register AP_ptr ap;
- {
- ap -> ap_obtype = APV_NIL;
- ap -> ap_obvalue = (char *) 0;
- ap -> ap_ptrtype = APP_NIL;
- ap -> ap_chain = (AP_ptr) 0;
- }
-
- ap_free (ap) /* free node's storage */
- register AP_ptr ap;
- {
- switch ((int)ap)
- { /* get rid of node, if have one */
- case OK:
- case NOTOK: /* nothing to free */
- break;
-
- default: /* actually have a node */
- switch ((int)(ap -> ap_obvalue))
- { /* get rid of its data string */
- case OK:
- case NOTOK: /* nothing to free */
- break;
-
- default:
- free (ap -> ap_obvalue);
- }
- free ((char *) ap);
- }
- }
-
- ap_fllnode (ap, obtype, obvalue) /* add data to node at end of chain */
- register AP_ptr ap;
- char obtype;
- register char *obvalue;
- {
- extern char *strdup ();
-
- ap -> ap_obtype = obtype;
- ap -> ap_obvalue = (obvalue == 0) ? (char *)0 : strdup (obvalue);
-
- #if DEBUG > 1
- if (debug)
- printf ("(%s/'%s')", typtab[obtype], obvalue);
- #endif
- }
-
- AP_ptr
- ap_new (obtype, obvalue) /* alloc & fill node */
- char obtype;
- char *obvalue;
- {
- register AP_ptr nap;
-
- nap = ap_alloc ();
- ap_fllnode (nap, obtype, obvalue);
- return (nap);
- }
-
- /* *************** LIST MANIPULATION PRIMITIVES ******************* */
-
- ap_insert (cur, ptrtype, new) /* create/fill/insert node in list */
- register AP_ptr cur; /* where to insert after */
- char ptrtype; /* inserted is more or new address */
- register AP_ptr new; /* where to insert after */
- {
- /* Now copy linkages from current node */
-
- new -> ap_ptrtype = cur -> ap_ptrtype;
- new -> ap_chain = cur -> ap_chain;
-
- /* Now point current node at inserted node */
-
- cur -> ap_ptrtype = ptrtype;
- cur -> ap_chain = new;
- }
-
- AP_ptr
- ap_sqinsert (cur, type, new) /* insert sequence */
- register AP_ptr cur,
- new;
- int type;
- {
- AP_ptr oldptr;
- int otype;
-
- switch ((int)new) {
- case OK:
- case NOTOK:
- return ((AP_ptr) 0);
- }
-
- oldptr = cur -> ap_chain;
- otype = cur -> ap_ptrtype;
- cur -> ap_chain = new;
- cur -> ap_ptrtype = type;
-
- while (new -> ap_ptrtype != APP_NIL &&
- new -> ap_chain != (AP_ptr) 0 &&
- new -> ap_chain -> ap_obtype != APV_NIL)
- new = new -> ap_chain;
-
- if (new -> ap_chain != (AP_ptr)0 && new -> ap_chain -> ap_obtype == APV_NIL)
- ap_delete (new);
-
- new -> ap_chain = oldptr;
- new -> ap_ptrtype = otype;
- return (new);
- }
-
- ap_delete (ap) /* remove next node in sequence */
- register AP_ptr ap;
- {
- register AP_ptr next;
-
- if (ap != (AP_ptr) 0 && ap -> ap_ptrtype != APP_NIL)
- { /* only if there is something there */
- next = ap -> ap_chain; /* link around one to be removed */
-
- ap -> ap_ptrtype = next -> ap_ptrtype;
- ap -> ap_chain = next -> ap_chain;
-
- ap_free (next);
- }
- }
-
- AP_ptr
- ap_append (ap, obtype, obvalue)
- /* alloc, fill, insert node */
- register AP_ptr ap; /* node to insert after */
- char obtype;
- char *obvalue;
- {
- register AP_ptr nap;
-
- nap = ap_alloc ();
- ap_fllnode (nap, obtype, obvalue);
- ap_insert (ap, APP_ETC, nap);
- return (nap);
- }
- /**/
-
- AP_ptr
- ap_add (ap, obtype, obvalue)
- /* try to append data to current node */
- register AP_ptr ap;
- char obtype;
- register char *obvalue;
- {
- extern char *multcat ();
- register char *ovalue;
-
- if (ap -> ap_obtype != obtype)
- return (ap_append (ap, obtype, obvalue));
- else /* same type or empty => can append */
- {
- if (obvalue == 0) /* No data to add */
- return (OK);
-
- if ((ovalue = ap -> ap_obvalue) == (char *) 0)
- ap_fllnode (ap, obtype, obvalue);
- else /* add to existing data */
- {
- ovalue = ap -> ap_obvalue;
- ap -> ap_obvalue = multcat (ovalue, " ", obvalue, (char *)0);
- free (ovalue);
- }
-
- #if DEBUG > 1
- if (debug)
- printf ("+%d/'%s')", obtype, obvalue);
- #endif
- }
- return (OK);
- }
-
- /**/
-
- AP_ptr
- ap_sqdelete (strt_node, end_node) /* remove nodes, through end node */
- register AP_ptr strt_node;
- register AP_ptr end_node;
- {
- switch ((int)strt_node) {
- case OK:
- case NOTOK:
- return ((AP_ptr)0);
- }
- while (strt_node -> ap_ptrtype != APP_NIL) {
- if (strt_node -> ap_chain == end_node) {
- /* last one requested */
- ap_delete (strt_node);
- return (strt_node -> ap_chain);
- }
- ap_delete (strt_node);
- }
- return ((AP_ptr) 0); /* end of chain */
- }
-
- AP_ptr
- ap_1delete (ap) /* remove all nodes of address to NXT */
- register AP_ptr ap; /* starting node */
- {
- while (ap -> ap_ptrtype != APP_NIL) {
- if (ap -> ap_ptrtype == APP_NXT)
- return (ap -> ap_chain);
- ap_delete (ap);
- }
- return ((AP_ptr) 0); /* end of chain */
- }
-
- ap_sqtfix (strt, end, obtype) /* alter obtype of a node subsequence */
- register AP_ptr strt;
- register AP_ptr end;
- register char obtype;
- {
- for ( ; ; strt = strt -> ap_chain) {
- if (strt -> ap_obtype != APV_CMNT)
- strt -> ap_obtype = obtype;
- if (strt == end || strt -> ap_ptrtype == APP_NIL)
- break;
- }
- }
-
- /**/
-
- AP_ptr
- ap_move (to, from) /* move node after from to be after to */
- register AP_ptr to,
- from;
- {
- register AP_ptr nodeptr;
-
- if (from -> ap_ptrtype == APP_NIL || from -> ap_chain == (AP_ptr) 0)
- return (from); /* quiet failure */
-
- nodeptr = from -> ap_chain;
-
- from -> ap_chain = nodeptr -> ap_chain;
- from -> ap_ptrtype = nodeptr -> ap_ptrtype;
-
- ap_insert (to, APP_ETC, nodeptr);
- return (from); /* next in chain, now */
- }
-
- AP_ptr
- ap_sqmove (to, from, endtype) /* move sequence */
- register AP_ptr to,
- from;
- register char endtype; /* copy only COMMENT and this */
- {
- switch ((int)from) {
- case OK:
- case NOTOK:
- return ((AP_ptr) 0);
- }
-
- while (from -> ap_ptrtype != APP_NIL && from -> ap_chain != (AP_ptr) 0) {
- if (endtype != (char) APV_NIL)
- if (from -> ap_obtype != APV_CMNT && from -> ap_obtype != endtype)
- break;
- to = ap_move (to, from);
- }
-
- return (to); /* end of chain */
- }
-
- /* ************************ PARSE STATE *************************** */
-
- AP_ptr ap_pstrt, /* current last node in parse tree */
- ap_pcur; /* current last node in parse tree */
-
- ap_iinit (gfunc) /* input function initialization */
- int (*gfunc) ();
- {
- ap_gfunc = gfunc; /* Set character fetch func */
- ap_peek = -1; /* No lex peek char */
- }
-
- ap_clear () /* Clear out the parser state */
- {
- ap_grplev = 0; /* Zero group nesting depth */
- ap_perlev = 0; /* Zero <> nesting depth */
- }
-
- AP_ptr
- ap_pinit (gfunc) /* init, alloc & set start node */
- int (*gfunc) ();
- {
- ap_iinit (gfunc);
- return (ap_pstrt = ap_pcur = ap_alloc ());
- }
-
- /* parse state saving uses a linked list of state information,
- * recorded in ap_prevstruct structures.
- * the list is manipulated as a simple stack.
- */
-
- ap_ppush (gfunc) /* save parse context, ap_iinit */
- int (*gfunc) ();
- {
- extern char *malloc ();
- register struct ap_prevstruct *tfil;
-
- /*NOSTRICT*/
- if ((tfil = (struct ap_prevstruct *) malloc (sizeof (*tfil))) ==
- (struct ap_prevstruct *) NULL)
- return (NOTOK);
-
- tfil -> ap_opeek = ap_peek; /* save regular parse state info */
- tfil -> ap_ogroup = ap_grplev;
- tfil -> ap_opersn = ap_perlev;
- tfil -> ap_prvgfunc = ap_gfunc;
- tfil -> ap_prvptr = ap_fle; /* save previous stack entry */
- ap_fle = tfil; /* save current stack entry */
- ap_iinit (gfunc); /* create new parse state */
- return (OK);
- }
-
- ap_ppop () /* restore previous parse state */
- {
- register struct ap_prevstruct *tfil;
-
- tfil = ap_fle;
- ap_peek = tfil -> ap_opeek;
- ap_grplev = tfil -> ap_ogroup;
- ap_perlev = tfil -> ap_opersn;
- ap_gfunc = tfil -> ap_prvgfunc;
- ap_fle = tfil -> ap_prvptr;
- free ((char *) tfil);
- }
- /**/
-
- /* the next three routines handle most of the overhead for acquiring
- * the address list from a file.
- */
-
- ap_flget () /* get character from included file */
- {
- register int c;
-
- c = getc (ap_fle -> ap_curfp);
-
- if (c == '\n')
- return (','); /* a minor convenience */
-
- return (c);
- }
-
- ap_fpush (file) /* indirect input from file */
- char file[];
- {
- if (ap_ppush (ap_flget) == NOTOK) /* save current & set for file input */
- return (NOTOK);
-
- if ((ap_fle -> ap_curfp = fopen (file, "r")) == (FILE *) NULL)
- { /* couldn't get the file, tho */
- ap_ppop ();
- return (NOTOK);
- }
- return (OK);
- }
-
- ap_fpop () /* pop the stack, if any input nested */
- {
- if (ap_fle -> ap_curfp != NULL)
- fclose (ap_fle -> ap_curfp);
-
- ap_ppop ();
- }
-
- /* ****************** PARSE LIST MANIPULATION ********************* */
-
- /* these echo the basic list manipuation primitives, but use ap_pcur
- * for the pointer and any insert will cause ap_pcur to be updated
- * to point to the new node.
- */
-
- ap_palloc () /* alloc, insert after pcur */
- {
- ap_pnsrt (ap_alloc (), APP_ETC);
- }
-
- ap_pfill (obtype, obvalue) /* add data to node at end of chain */
- char obtype;
- register char *obvalue;
- {
- extern char *strdup ();
-
- ap_pcur -> ap_obtype = obtype;
- ap_pcur -> ap_obvalue =
- (obvalue == (char *) 0) ? (char *) 0 : strdup (obvalue);
- #if DEBUG > 1
- if (debug)
- printf ("(%s/'%s')", typtab[obtype], obvalue);
- #endif
- }
-
- ap_pnsrt (ap, ptrtype) /* add node to end of parse chain */
- register AP_ptr ap;
- char ptrtype;
- {
- register AP_ptr rap_pcur;
-
- if ((rap_pcur = ap_pcur) -> ap_obtype == APV_NIL)
- { /* current one can be used */
- rap_pcur -> ap_obtype = ap -> ap_obtype;
- rap_pcur -> ap_obvalue = ap -> ap_obvalue;
- ap -> ap_obvalue = 0;
- ap_free (ap);
- } else { /* really do the insert */
- rap_pcur -> ap_ptrtype = ptrtype;
- rap_pcur -> ap_chain = ap;
- ap_pcur = ap;
- }
- }
-
- ap_pappend (obtype, obvalue) /* alloc, fill, append at end */
- char obtype;
- char *obvalue;
- {
- ap_palloc (); /* will update pcur */
- ap_fllnode (ap_pcur, obtype, obvalue);
- }
-
- ap_padd (obtype, obvalue) /* try to append data to current node */
- char obtype;
- char *obvalue;
- {
- register AP_ptr nap;
-
- nap = ap_add (ap_pcur, obtype, obvalue);
-
- if (nap != OK) /* created new node */
- ap_pcur = nap;
- }
-